<?php if (!defined('CORE_DIR')) die('Wrong entry point!');

/* 
 * Copyright 2010 Anton Muraviev a.k.a kuromaisu
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */

Aero::define('MarkdownSpecification', AS_SINGLETON);

/*
 * ViewLibrarySpecification
 */
class MarkdownSpecification extends AeroSpec
{
	protected $MD;
	protected $test_paths;
	private $markdown_tests;
	
	public function __construct()
	{
		if (empty($this->test_paths))
		{
			$this->test_paths = array(
				Aero::basePath() . 'specs/markdown_tests/original',
				Aero::basePath() . 'specs/markdown_tests/additional'
			);
		}
		
		if (empty($this->MD))
		{
			$this->MD = Aero::load('libs/parsers/markdown');
		}
		
		parent::__construct();
	}
	
	protected function getBehaviors()
	{
		foreach ($this->test_paths as $path)
		{
			if (!file_exists($path) || !is_dir($path))
			{
				continue;
			}
			
			// List all files in the directory
			$files = scandir($path);
			
			foreach ($files as $file)
			{
				if (in_array($file, array('.','..')) || is_dir($file))
				{
					continue;
				}
				
				$parts = explode('.',$file);
				$ext = array_pop($parts);
				$file = implode($parts);
				$this->markdown_tests['pass &ldquo;'.$file.'&rdquo; test'][$ext] = $path . '/' . $file . '.' . $ext;
			}
		}
		
		return array_combine(array_keys($this->markdown_tests), array_keys($this->markdown_tests));
	}
	
	function checkBehavior($hash)
	{
		if (!isset($this->markdown_tests[$hash]))
		{
			throw new AeroSpecSkipped('Behavior has not been defined corrently.');
		}
		else if (!isset($this->markdown_tests[$hash]['text']))
		{
			throw new AeroSpecSkipped('Markdown file could not be found.');
		}
		else if (!isset($this->markdown_tests[$hash]['xhtml']))
		{
			throw new AeroSpecSkipped('XHTML file could not be found.');
		}
		
		$txt = file_get_contents($this->markdown_tests[$hash]['text']);
		$html =  $this->_fixEscapedChars(file_get_contents($this->markdown_tests[$hash]['xhtml']));
		$_html = $this->_fixEscapedChars($this->MD->transform($txt));
		
		$this->html($_html)->isSimilarTo($html);
	}
	
	protected function _fixEscapedChars($string)
	{
		// Unescape &gt;
		$string = str_replace('&gt;','>', $string);
		return preg_replace_callback('~&#(x?)([a-z0-9]+);~i', array($this,'_unescapeChar'), $string);
	}

	public function _unescapeChar($ref)
	{
		$ascii = !empty($ref[1]) ? hexdec($ref[2]) : $ref[2];
		return chr($ascii);
	}
}